package com.mh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.mh.dao.AccountBookDao;
import com.mh.dao.UserDao;
import com.mh.dto.bo.WeChatSessionModel;
import com.mh.dto.vo.R;
import com.mh.pojo.AccountBook;
import com.mh.pojo.User;
import com.mh.service.UserService;
import com.mh.utils.JWTUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 用户表(User)表服务实现类
 *
 * @author zmh
 * @since 2025-02-08 09:18:50
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {

    private final UserDao userDao;

    private final RestTemplate restTemplate; // 发送网络请求 - 微信登录

    private final AccountBookDao accountBookDao; // 账本管理

    private final RabbitTemplate rabbitTemplate;


    @Value("${APPID}")
    private String appid;

    @Value("${APPSECRET}")
    private String appsecret;

    /**
     * 分页查询
     *
     * @param page 查询页数
     * @param size 一页显示条数
     * @return ·
     */
    public R<Page<User>> getAllByPage(int page, int size) {
        Page<User> userPage = new Page<>(page, size);
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        //TODO 查询条件定制
        return R.success(userDao.selectPage(userPage, queryWrapper));
    }

    /**
     * 登录验证
     * @param code 临时登录码
     * @return ·
     */
    @Override
    public Map<String, Object> checkLogin(String code) {


        // 用于返回登录结果
        Map<String,Object> map = new HashMap<>();

        // 根据传入code，调用微信服务器，获取唯一openid
        // 微信服务器接口地址
        String url = "https://api.weixin.qq.com/sns/jscode2session?appid="+appid+ "&secret="+appsecret
                +"&js_code="+ code +"&grant_type=authorization_code";
        String errmsg = "";
        String errcode = "";
        String session_key = "";
        String openid = "";
        WeChatSessionModel weChatSessionModel;
        // 发送请求，获取openID
        ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.GET, null, String.class);
        if(responseEntity.getStatusCode() == HttpStatus.OK) {
            String sessionData = responseEntity.getBody();
            Gson gson = new Gson();
            //将json字符串转化为实体类;
            weChatSessionModel = gson.fromJson(sessionData, WeChatSessionModel.class);
            log.info("返回的数据==>{}",weChatSessionModel);
            //获取用户的唯一标识
            openid = weChatSessionModel.getOpenid();
            //获取会话秘钥（具有时效性，用户登录的临时通行证）
            //登录后前端的每次接口请求都需带上session_key
            session_key = weChatSessionModel.getSession_key();
            //获取错误码
            errcode = weChatSessionModel.getErrcode();
            //获取错误信息
            errmsg = weChatSessionModel.getErrmsg();
        }else{
            log.info("出现错误，错误信息：{}",errmsg );
            map.put("errmsg",errmsg);
            return map;
        }

        // 判断是否成功获取到openid
        if ("".equals(openid) || openid == null){
            log.info("错误获取openid,错误信息:{}",errmsg);
            map.put("errmsg",errmsg);
            return map;
        }else{
            // 判断用户是否存在(是否已注册)
            // 构造查询条件
            LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(User::getOpenid, openid);
            User user = userDao.selectOne(queryWrapper);
            // 不存在，加入数据库 （走注册逻辑）
            if (user == null){
                // 填充初始信息
                User registerUser = new User(openid, "微信用户", "defualt_avatar.jpg");
                userDao.insert(registerUser);// 加入数据库

                // 注册成功，异步给MQ发消息，给新用户添加默认账本
                rabbitTemplate.convertAndSend("addBookForNewUser", openid);

                map.put("user", registerUser);
                String token = JWTUtils.createToken(registerUser.getOpenid());
                map.put("token",token);
                return map;
            }else{
                // 存在，将用户信息加入map返回
                map.put("user",user);
                String token = JWTUtils.createToken(user.getOpenid().toString());
                map.put("token",token);
                return map;
            }
        }
    }

    /**
     * 通过openId获取用户ID
     * @param openId 用户的openId
     * @return UserId
     */
    @Override
    public Integer getUserIdByOpenId(String openId) {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getOpenid, openId);
        User user = userDao.selectOne(userLambdaQueryWrapper);

        if(user != null){
            return user.getId();
        }
        return 0;
    }

    /**
     * 为新用户添加默认账本
     * @param openId 微信openID
     * @return 执行结果
     */
    @Override
    public Boolean addDefaultBookForNewUser(String openId) {
        // 根据openID获取用户ID
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getOpenid, openId);
        User user = userDao.selectOne(queryWrapper);

        // 用户不存在
        if(user == null){
            return false;
        }

        // 添加默认账本数据
        AccountBook accountBook = new AccountBook(null, user.getId(), "默认账本",
                1, "CNY", 1, null, null);

        return accountBookDao.insert(accountBook) == 1;
    }
}

